package dontCare.gwtester.client.tool;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.Widget;

import dontCare.gwtester.client.GWTesterEP;

public class TestShower extends Composite{
	private static TestShowerUiBinder uiBinder = GWT.create(TestShowerUiBinder.class);
	interface TestShowerUiBinder extends UiBinder<Widget, TestShower> {}

	@UiField Tree tree;
	
	private static final String PGK_HEADER = "dontCare.gwtester.client";
	private TreeNode rootNode = new TreeNode(null);
	private ArrayList<UnitWidget> allUnit;
	
	public TestShower(ArrayList<UnitWidget> allUnit) {
		initWidget(uiBinder.createAndBindUi(this));
		this.allUnit = allUnit;
		parseHash();
	}

	private void parseHash() {
		for(UnitWidget c : allUnit){
			rootNode.addChild(c, 0);
		}
		for(TreeNode node : rootNode.getChild()){
			tree.addItem(buildTree(node));
		}
	}
	
	private TreeItem buildTree(final TreeNode node){
		if(node.isLeaf()){
			Label nodeLbl = new Label(node.getC1ass().getName());
			nodeLbl.setStyleName("treeLeaf");
			nodeLbl.addClickHandler(new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					GWTesterEP.container.clear();
					GWTesterEP.container.add(
						new TestPanel(node.getC1ass())
					);
				}
			});
			TreeItem root = new TreeItem(nodeLbl);
			return root;
		}else{
			TreeItem root = new TreeItem(node.getValue());
			root.setStyleName("treeRoot"); 
			for(TreeNode n : node.getChild()){
				root.addItem(buildTree(n));
			}
			return root;
		}
	}
	
	private class TreeNode {
		private String value;
		private UnitWidget c1ass;
		private ArrayList<TreeNode> child = new ArrayList<TreeNode>();
		
		public TreeNode(String value){
			this.value = value;
		}
		
		public void addChild(UnitWidget c, int level){
			List<String> list = Arrays.asList(c.getClass().getName().substring(PGK_HEADER.length()+1).split("[..]"));

			TreeNode tmp = new TreeNode(list.get(level));
			tmp.c1ass = c;
			
			int index = child.indexOf(tmp);
			if(index==-1){
				child.add(tmp);
				index = child.indexOf(tmp);
			}

			if(list.size()>level+1){	//還有 child
				child.get(index).addChild(c, level+1);
			}
		}
		
		public ArrayList<TreeNode> getChild(){
			return child;
		}
		
		public boolean isLeaf(){
			return child.size()==0;
		}
		
		public String getValue(){
			return value;
		}
		
		public UnitWidget getC1ass() {
			return c1ass;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			TreeNode other = (TreeNode) obj;
			if (value == null) {
				if (other.value != null)
					return false;
			} else if (!value.equals(other.value))
				return false;
			return true;
		}

		@Override
		public int hashCode() {
			return super.hashCode();
		}
	}
}

